#include<ratio>
#include<iostream>
#include<numeric>

using namespace std;

template <size_t N>
constexpr size_t AddN = std::ratio_add<std::ratio<N>, std::ratio<1>>::num;

template <size_t N>
constexpr size_t DecN = std::ratio_subtract<std::ratio<N>, std::ratio<1>>::num;

template<size_t X, size_t N>
constexpr size_t PowN = std::ratio_multiply<std::ratio<X>, std::ratio<PowN<X, DecN<N>>>>::num;

template<size_t X>
constexpr size_t PowN<X, 0> = 1;

namespace ORDetail
{
	template<size_t N>
	constexpr size_t _GetBin = std::ratio_greater_v<std::ratio<std::ratio_divide<std::ratio<N>, std::ratio<2>>::den>, std::ratio<1>> ? 1 : 0;

	template<size_t N>
	constexpr size_t _RightShift = _GetBin<N> ? std::ratio_divide<std::ratio<DecN<N>>, std::ratio<2>>::num : std::ratio_divide<std::ratio<N>, std::ratio<2>>::num;

	//template<size_t N1, size_t N2, size_t X = 0>
	//constexpr size_t _OR = std::ratio_multiply<std::ratio<_GetBin<N1> | _GetBin<N2>>, std::ratio<PowN<2, X>>>::num;

	template<size_t N1, size_t N2>
	constexpr size_t OR = N1 | N2;
}
#if 0


template<size_t X, size_t N>
constexpr size_t Sqrt<X, N, X> = X;
template<size_t N>
constexpr size_t Sqrt<2, N> = 1;
template<>
constexpr size_t Sqrt<2, 1> = 2;
#endif // 0

int main()
{
	cout << ORDetail::_GetBin<0> << endl;
	cout << ORDetail::_GetBin<1> << endl;
	cout << ORDetail::_GetBin<2> << endl;
	cout << ORDetail::_GetBin<3> << endl;
	cout << ORDetail::_GetBin<4> << endl;
	cout << endl;
	cout << ORDetail::_RightShift<0> << endl;
	cout << ORDetail::_RightShift<1> << endl;
	cout << ORDetail::_RightShift<2> << endl;
	cout << ORDetail::_RightShift<3> << endl;
	cout << ORDetail::_RightShift<4> << endl;
	cout << endl;
	cout << ORDetail::OR<0, 1> << endl;
	cout << ORDetail::OR<1, 1> << endl;
	cout << ORDetail::OR<2, 1> << endl;
	cout << ORDetail::OR<3, 1> << endl;
	cout << ORDetail::OR<4, 1> << endl;

	return 0;
}